require 'rake/clean'
require 'rake/testtask'

require 'logger'
$LOG = Logger.new('expression.log')
$LOG.level = Logger::INFO

require 'micro_proj'
require 'yaml'

require 'rubygems'
require 'ruby-debug'


Debugger.start
# debugger
$: << Dir.getwd + "/lib/con_code" << Dir.getwd + "/lib"
$: << Dir.getwd + "/lib/con_code/plugins"


# Override CLEAN's include so that it records in the project
# which files are to be cleaned
class <<CLEAN
	def include_persisted(arg, proj)
		self.include(arg)
		proj.set_clean( self.entries )
	end
end

directory "raw_data"

TRIM_DIR = "trimmed_files/"
directory TRIM_DIR
CON_DIR = "con_files/"
directory CON_DIR
GROUP_DIR = "grouped_files/"
directory GROUP_DIR

MICRO_EXPRE_TRIM = FileList[TRIM_DIR + "US*.txt"]
MICRO_EXPRE_CON = FileList[CON_DIR + "US*.txt"]
MICRO_EXPRE_GROUPED = FileList[GROUP_DIR + "US*.txt"]

CLEAN.include(MICRO_EXPRE_TRIM)
CLEAN.include(MICRO_EXPRE_CON)
CLEAN.include(TRIM_DIR)
CLEAN.include(CON_DIR)



##-------------------------------------------
##----------------- Tests -------------------

desc "Run unit tests"
Rake::TestTask.new("test_units") do |t|
	$: << Dir.getwd + "/tests/"

	t.pattern = 'tests/*_test.rb'
	t.verbose = false 
	t.warning = false
end

Rake::TestTask.new("test_units_v") do |t|
	$: << Dir.getwd + "/tests/"

	t.pattern = 'tests/*_test.rb'
	t.verbose = true
	t.warning = true
end


##-------------------------------------------
##------------- Project Stuff ---------------

# Create a default project file
file "project.yaml" do |t|
	$LOG.warn( "Project file not found... creating default: project.yaml" )

	p = MicroProject.new(FileList['US*.txt'].entries)
	p.write
end


# Load the project file
task :LoadProject => ["project.yaml"] do 
	@project = YAML::load_file("project.yaml")
	MICRO_EXPRE_RAW = FileList[@project.raw_files]
	CLEAN.include(@project.clean)
	$LOG.info( "Loaded project file. \nRaw Files:\n\t#{MICRO_EXPRE_RAW.entries.join("\n\t")}\n\n" )
end

task :WriteProject => [:LoadProject] do
	@project.write
end

task :DelProject do
	File.delete("project.yaml") if File.exists?("project.yaml")
end


##-------------------------------------------
##-------------- Trim Files -----------------

# Trim individual files
rule(%r{#{TRIM_DIR}US.*\.txt} => [proc {|f| f.sub( TRIM_DIR, '' )}]) do |t|
	require "lib/trim_micro_data"
	$LOG.info "Trimming #{t.source}..."
	trim_microarray(t.source, t.name)
end


# Batch trim
# Attempts to trim all of the expression files in this directory
desc "Trim all of the US*.txt files in the base directory"

task :ExpreTrim => [TRIM_DIR, :LoadProject] do
	MICRO_EXPRE_RAW.each {|file| Rake::Task[TRIM_DIR + file].invoke} 
	MICRO_EXPRE_TRIM.include(TRIM_DIR + "US*.txt")

	$LOG.info "Files Trimmed"
end


##-------------------------------------------
##------------ Condense Files ---------------
# Condense a file
desc "Flatten One file"

rule(%r{#{CON_DIR}US.*\.txt} => [ proc {|f| f.sub(CON_DIR, TRIM_DIR)} ]) do |t|
	require "lib/con_code/expre"
	fc = FileCondense.new(t.source)
	fc.parse_all
	fc.to_file(t.name)
end

# Batch Condense
desc "Flatten all of the files"

task :ExpreCondense => [CON_DIR, :ExpreTrim] do
	MICRO_EXPRE_TRIM.each {|file| Rake::Task[file.sub(TRIM_DIR, CON_DIR)].invoke}

	$LOG.info "Files Condensed"
end



#----------------
# Merge all files 
desc "Merge all of the files into one"

task :MergeAll => [:ExpreCondense] do
	sh "R < lib/con_merge.R --no-save --slave --args --in_files=#{MICRO_EXPRE_CON.join(',')} --out_file=merged.txt"
end


#----------------------------
# Group the probes for a file

rule(%r{#{GROUP_DIR}US.*\.txt} => [ proc {|f| f.sub(GROUP_DIR, TRIM_DIR)} ]) do |t|
	require "lib/con_code/expre"
	fc = FileCondense.new(t.source)
	fc.parse_all
	$LOG.info "Grouping #{t.name}"
	fc.write_grouped_probes(t.name)
end

# Batch Condense
desc "Groups the probes out of the trimmed files"

task :ExpreGroup => [GROUP_DIR, :ExpreTrim] do
	MICRO_EXPRE_TRIM.each {|file| Rake::Task[file.sub(TRIM_DIR, GROUP_DIR)].invoke}

	$LOG.info "Probes Grouped"
end



##-------------------------------------------
##-------------------------------------------

# Delete all of the files in a FileList
def cleanFileList( in_list )
	in_list.each {|f| sh "rm  #{f}"}
end

desc "Clean only the flattened files"
task :CleanCons do |t|
	cleanFileList( MICRO_EXPRE_CON )
	sh "rm -r #{CON_DIR}"
end

desc "Clean the grouped files"
task :CleanGrouped do |t|
	cleanFileList( MICRO_EXPRE_GROUPED )
	sh "rm -r #{GROUP_DIR}"
end


desc "Trim and merge raw data files"
task :default => [:DelProject, :test_units, :ExpreCondense, :ExpreTrim]

task :clean => [:LoadProject]


def get_trimmed_name(name)
	name + ".trim"
end

